package ar.com.age.distribuidora.presentacion.controller;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.primefaces.context.RequestContext;

import ar.com.age.distribuidora.dominio.Cobro;
import ar.com.age.distribuidora.dominio.EntregaCheque;
import ar.com.age.distribuidora.dominio.EntregaEfectivo;
import ar.com.age.distribuidora.dominio.MovimientoCheque;
import ar.com.age.distribuidora.presentacion.util.Mensajes;
import ar.com.age.distribuidora.presentacion.util.ServiceLocator;
import ar.com.age.distribuidora.presentacion.util.ValidadorTipoUsuario;

@ManagedBean
@ViewScoped
public class CobroBean {

	private String codigoRegistrar;
	
	private String comentarioRegistrar;
	
	private Date fechaCobroRegistrar;
	
	private EntregaEfectivo entregaEfectivoSeleccionadoRegistrar;
	
	private EntregaCheque entregaChequeSeleccionadoRegistrar;

	private EntregaEfectivo entregaEfectivoSeleccionadoEditar;

	private EntregaCheque entregaChequeSeleccionadoEditar;
	
	private String montoRegistrar;
	
	private List<EntregaEfectivo> entregasEfectivo;
	
	private List<EntregaCheque> entregasCheque;
	
	private List<Cobro> cobros;
	
	private Cobro cobroSeleccionado;  
    
	private Cobro cobroSeleccionadoDetalles;
	
	private String montoEditar;
    
	private String codigoBuscar;
	
	private String estadoBuscar;
	
	private Date fechaDesdeBuscar;
	
	private Date fechaHastaBuscar;

	private boolean panelBuscarVisibilidad;
	
	private boolean panelEditarVisibilidad;

	private boolean panelRegistrarVisibilidad;
	
    
	public CobroBean() {

		ValidadorTipoUsuario.validarEmpleadoVenta();
		
		this.entregasEfectivo = ServiceLocator.getEntregaService().buscarTodosEntregaEfectivo();
		this.entregasCheque = ServiceLocator.getEntregaService().buscarTodosEntregaCheque();

		this.panelEditarVisibilidad = false;
		this.panelRegistrarVisibilidad = true;
		this.panelBuscarVisibilidad = false;

	}
	
	public boolean isPanelBuscarVisibilidad() {
		return panelBuscarVisibilidad;
	}

	public void setPanelBuscarVisibilidad(boolean panelBuscarVisibilidad) {
		this.panelBuscarVisibilidad = panelBuscarVisibilidad;
	}

	public boolean isPanelEditarVisibilidad() {
		return panelEditarVisibilidad;
	}

	public void setPanelEditarVisibilidad(boolean panelEditarVisibilidad) {
		this.panelEditarVisibilidad = panelEditarVisibilidad;
	}

	public boolean isPanelRegistrarVisibilidad() {
		return panelRegistrarVisibilidad;
	}

	public void setPanelRegistrarVisibilidad(boolean panelRegistrarVisibilidad) {
		this.panelRegistrarVisibilidad = panelRegistrarVisibilidad;
	}

	public String getCodigoRegistrar() {
		return codigoRegistrar;
	}

	public void setCodigoRegistrar(String codigoRegistrar) {
		this.codigoRegistrar = codigoRegistrar;
	}

	public String getComentarioRegistrar() {
		return comentarioRegistrar;
	}

	public void setComentarioRegistrar(String comentarioRegistrar) {
		this.comentarioRegistrar = comentarioRegistrar;
	}

	public Date getFechaCobroRegistrar() {
		return fechaCobroRegistrar;
	}

	public void setFechaCobroRegistrar(Date fechaCobroRegistrar) {
		this.fechaCobroRegistrar = fechaCobroRegistrar;
	}

	public EntregaEfectivo getEntregaEfectivoSeleccionadoRegistrar() {
		return entregaEfectivoSeleccionadoRegistrar;
	}

	public void setEntregaEfectivoSeleccionadoRegistrar(
			EntregaEfectivo entregaEfectivoSeleccionadoRegistrar) {
		this.entregaEfectivoSeleccionadoRegistrar = entregaEfectivoSeleccionadoRegistrar;
	}

	public EntregaCheque getEntregaChequeSeleccionadoRegistrar() {
		return entregaChequeSeleccionadoRegistrar;
	}

	public void setEntregaChequeSeleccionadoRegistrar(
			EntregaCheque entregaChequeSeleccionadoRegistrar) {
		this.entregaChequeSeleccionadoRegistrar = entregaChequeSeleccionadoRegistrar;
	}

	public EntregaEfectivo getEntregaEfectivoSeleccionadoEditar() {
		return entregaEfectivoSeleccionadoEditar;
	}

	public void setEntregaEfectivoSeleccionadoEditar(
			EntregaEfectivo entregaEfectivoSeleccionadoEditar) {
		this.entregaEfectivoSeleccionadoEditar = entregaEfectivoSeleccionadoEditar;
	}

	public EntregaCheque getEntregaChequeSeleccionadoEditar() {
		return entregaChequeSeleccionadoEditar;
	}

	public void setEntregaChequeSeleccionadoEditar(
			EntregaCheque entregaChequeSeleccionadoEditar) {
		this.entregaChequeSeleccionadoEditar = entregaChequeSeleccionadoEditar;
	}

	public String getMontoRegistrar() {
		return montoRegistrar;
	}

	public void setMontoRegistrar(String montoRegistrar) {
		this.montoRegistrar = montoRegistrar;
	}

	public List<EntregaEfectivo> getEntregasEfectivo() {
		return entregasEfectivo;
	}

	public void setEntregasEfectivo(List<EntregaEfectivo> entregasEfectivo) {
		this.entregasEfectivo = entregasEfectivo;
	}

	public List<EntregaCheque> getEntregasCheque() {
		return entregasCheque;
	}

	public void setEntregasCheque(List<EntregaCheque> entregasCheque) {
		this.entregasCheque = entregasCheque;
	}

	public List<Cobro> getCobros() {
		return cobros;
	}

	public void setCobros(List<Cobro> cobros) {
		this.cobros = cobros;
	}

	public Cobro getCobroSeleccionado() {
		return cobroSeleccionado;
	}

	public void setCobroSeleccionado(Cobro cobroSeleccionado) {
		this.cobroSeleccionado = cobroSeleccionado;
	}

	public Cobro getCobroSeleccionadoDetalles() {
		return cobroSeleccionadoDetalles;
	}

	public void setCobroSeleccionadoDetalles(Cobro cobroSeleccionadoDetalles) {
		this.cobroSeleccionadoDetalles = cobroSeleccionadoDetalles;
	}

	public String getMontoEditar() {
		return montoEditar;
	}

	public void setMontoEditar(String montoEditar) {
		this.montoEditar = montoEditar;
	}

	public String getCodigoBuscar() {
		return codigoBuscar;
	}
	
	public String getEstadoBuscar() {
		return estadoBuscar;
	}

	public void setEstadoBuscar(String estadoBuscar) {
		this.estadoBuscar = estadoBuscar;
	}
	
	public void setCodigoBuscar(String codigoBuscar) {
		this.codigoBuscar = codigoBuscar;
	}

	public Date getFechaDesdeBuscar() {
		return fechaDesdeBuscar;
	}

	public void setFechaDesdeBuscar(Date fechaDesdeBuscar) {
		this.fechaDesdeBuscar = fechaDesdeBuscar;
	}

	public Date getFechaHastaBuscar() {
		return fechaHastaBuscar;
	}

	public void setFechaHastaBuscar(Date fechaHastaBuscar) {
		this.fechaHastaBuscar = fechaHastaBuscar;
	}


	
	// Metodos del Bean

	public String registrarCobro() {
		
		// para ver que se haya seleccionado en uno de los dos combo
		if (!(entregaChequeSeleccionadoRegistrar == null) && (entregaEfectivoSeleccionadoRegistrar == null) || !(entregaChequeSeleccionadoRegistrar != null) && (entregaEfectivoSeleccionadoRegistrar != null)) {
			
			// para ver que la entrega seleccionada no este agotada
			if ((entregaChequeSeleccionadoRegistrar != null && !entregaChequeSeleccionadoRegistrar.getEstado().equals("Agotada")) || (entregaEfectivoSeleccionadoRegistrar != null && !entregaEfectivoSeleccionadoRegistrar.getEstado().equals("Agotada"))) {

				// para ver que el monto del combro no sea superior al disponible de la entrega
				if ((entregaChequeSeleccionadoRegistrar != null && (entregaChequeSeleccionadoRegistrar.getMontoActual() >= Double.parseDouble(montoRegistrar))) || (entregaEfectivoSeleccionadoRegistrar != null && (entregaEfectivoSeleccionadoRegistrar.getMontoActual() >= Double.parseDouble(montoRegistrar)))) {
					
					Cobro cobro = new Cobro();
					cobro.setCodigo(codigoRegistrar);
					cobro.setComentario(comentarioRegistrar);
					cobro.setFecha(fechaCobroRegistrar);
					cobro.setEstado("Disponible");
					cobro.setMonto(Double.parseDouble(montoRegistrar));
					if (entregaChequeSeleccionadoRegistrar != null) {
						cobro.setEntrega(entregaChequeSeleccionadoRegistrar);
						
						// Registro el Movimiento para la Auditoria de Cheques
						MovimientoCheque movimiento = new MovimientoCheque();
						movimiento.setCheque(entregaChequeSeleccionadoRegistrar.getCheque());
						Date fecha = Calendar.getInstance().getTime();
						movimiento.setFecha(fecha);
						movimiento.setTipo(Mensajes.REGISTRO_CHEQUE);
						ServiceLocator.getAuditoriaChequeService().crearOEditarMovimientoCheque(movimiento);
						
					} else {
						cobro.setEntrega(entregaEfectivoSeleccionadoRegistrar);
					}
					
					ServiceLocator.getVentaService().crearOEditarCobro(cobro);
					
					FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Advertencia", "La operacion se ha realizado con exito.");  
					RequestContext.getCurrentInstance().showMessageInDialog(message);
					
					fechaCobroRegistrar = null;
					comentarioRegistrar = null;
					entregaEfectivoSeleccionadoRegistrar = null;
					entregaChequeSeleccionadoRegistrar = null;
					montoRegistrar = null;
					codigoRegistrar = null;
					
					return null;
					
				} else {
					
					FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "El monto del cobro es superior al disponible de la entrega");  
					RequestContext.getCurrentInstance().showMessageInDialog(message);
					
					fechaCobroRegistrar = null;
					comentarioRegistrar = null;
					entregaEfectivoSeleccionadoRegistrar = null;
					entregaChequeSeleccionadoRegistrar = null;
					montoRegistrar = null;
					codigoRegistrar = null;
					
					return null;
				}

			} else {

				FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "La entrega seleccionada esta agotada");  
				RequestContext.getCurrentInstance().showMessageInDialog(message);
				
				fechaCobroRegistrar = null;
				comentarioRegistrar = null;
				entregaEfectivoSeleccionadoRegistrar = null;
				entregaChequeSeleccionadoRegistrar = null;
				montoRegistrar = null;
				codigoRegistrar = null;
				
				return null;
			}
			
		} else {
			
			FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "Debe seleccionar una entrega");  
			RequestContext.getCurrentInstance().showMessageInDialog(message);
			
			return null;
		}
		
	}
	
	
	public String actualizarCobro() {

		if (!(entregaChequeSeleccionadoEditar == null) && (entregaEfectivoSeleccionadoEditar == null) || !(entregaChequeSeleccionadoEditar != null) && (entregaEfectivoSeleccionadoEditar != null)) {

			// para calcular el futuro monto antes de la edicion
			Double monto = new Double(0.0);
			if (entregaChequeSeleccionadoEditar != null) {
				monto = entregaChequeSeleccionadoEditar.getMontoActual() + cobroSeleccionado.getMonto();
			} else {
				monto = entregaEfectivoSeleccionadoEditar.getMontoActual() + cobroSeleccionado.getMonto();
			}

			// para ver que el monto del combro no sea superior al disponible de la entrega
			if ((entregaChequeSeleccionadoEditar != null && (monto >= Double.parseDouble(montoEditar))) || (entregaEfectivoSeleccionadoEditar != null && (monto >= Double.parseDouble(montoEditar)))) {

				if (this.cobroSeleccionado != null) {

					FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Cobro",  "Cobro editado con exito.");  
					RequestContext.getCurrentInstance().showMessageInDialog(message);
					
					
					//si se elige otra entrega, actualizo el monto de la entrega anterior
					if (entregaChequeSeleccionadoEditar != null) {

						if(cobroSeleccionado.getEntrega().getId() != entregaChequeSeleccionadoEditar.getId()){
							
							cobroSeleccionado.getEntrega().setMontoActual(cobroSeleccionado.getEntrega().getMontoActual() + cobroSeleccionado.getMonto());
							if (cobroSeleccionado.getEntrega().getClass().equals(EntregaCheque.class)) {
								
								ServiceLocator.getEntregaService().crearOEditarEntregaCheque((EntregaCheque)cobroSeleccionado.getEntrega());

							} else {

								ServiceLocator.getEntregaService().crearOEditarEntregaEfectivo((EntregaEfectivo)cobroSeleccionado.getEntrega());
							}
						}

					} else {

						if(cobroSeleccionado.getEntrega().getId() != entregaEfectivoSeleccionadoEditar.getId()){

							cobroSeleccionado.getEntrega().setMontoActual(cobroSeleccionado.getEntrega().getMontoActual() + cobroSeleccionado.getMonto());
							if (cobroSeleccionado.getEntrega().getClass().equals(EntregaCheque.class)) {

								ServiceLocator.getEntregaService().crearOEditarEntregaCheque((EntregaCheque)cobroSeleccionado.getEntrega());

							} else {

								ServiceLocator.getEntregaService().crearOEditarEntregaEfectivo((EntregaEfectivo)cobroSeleccionado.getEntrega());
							}						
						}
					}

					
					//si la entrega seleccionada es la misma, sumo a la entrega el monto que se le habia descontado prevamente para luego restar el nuevo montoEditar
					if (entregaChequeSeleccionadoEditar != null) {
						if (entregaChequeSeleccionadoEditar.getId().equals(cobroSeleccionado.getEntrega().getId())) {
							
							entregaChequeSeleccionadoEditar.setMontoActual(entregaChequeSeleccionadoEditar.getMontoActual() + cobroSeleccionado.getMonto());
						}

					} else {

						if (entregaEfectivoSeleccionadoEditar.getId().equals(cobroSeleccionado.getEntrega().getId())) {
							entregaEfectivoSeleccionadoEditar.setMontoActual(entregaEfectivoSeleccionadoEditar.getMontoActual() + cobroSeleccionado.getMonto());
						}
					}


					this.cobroSeleccionado.setMonto(Double.parseDouble(montoEditar));
					if (entregaChequeSeleccionadoEditar != null) {
						cobroSeleccionado.setEntrega(entregaChequeSeleccionadoEditar);
					} else {
						cobroSeleccionado.setEntrega(entregaEfectivoSeleccionadoEditar);
					}

					ServiceLocator.getVentaService().crearOEditarCobro(this.cobroSeleccionado);

					this.cobroSeleccionado = null;
					this.montoEditar = null;
					this.entregaChequeSeleccionadoEditar = null;
					this.entregaEfectivoSeleccionadoEditar = null;
					
					this.panelEditarVisibilidad = false;
					this.panelRegistrarVisibilidad = true;

					return null;
				} else {

					FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Cobro",  "No se ha seleccionado un elemento.");  
					FacesContext.getCurrentInstance().addMessage(null, message);  
					return null;
				}

			} else {

				FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "El monto del cobro es superior al disponible de la entrega");  
				RequestContext.getCurrentInstance().showMessageInDialog(message);

				this.cobroSeleccionado = null;
				entregaEfectivoSeleccionadoEditar = null;
				entregaChequeSeleccionadoEditar = null;
				montoEditar = null;

				return null;
			}


		} else {

			FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Error", "Debe serleccionar una entrega");  
			RequestContext.getCurrentInstance().showMessageInDialog(message);

			return null;
		}
	}
	
	public String editarCobro() {
		
		if (this.cobroSeleccionado != null) {
			
			this.panelEditarVisibilidad = true;
			this.panelRegistrarVisibilidad = false;
			this.panelBuscarVisibilidad = false;
			
			this.montoEditar = String.valueOf(this.cobroSeleccionado.getMonto());
			
			return null;

		} else {
			
			FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Advertencia", "No ha seleccionado ningun elemento.");  
	        RequestContext.getCurrentInstance().showMessageInDialog(message);
			return null;
		}	

	}
	
	public String eliminarCobro() {
		
		if (this.cobroSeleccionado != null) {
			
			try {
					ServiceLocator.getVentaService().eliminarCobro(this.cobroSeleccionado);
				} catch (Exception e) {
				
				FacesMessage message2 = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", Mensajes.ELEMENTO_ASIGNADO);  
		        RequestContext.getCurrentInstance().showMessageInDialog(message2);
				return null;
			}
			
			this.cobroSeleccionado = null;
			this.montoEditar = null;
			
			this.cobros = ServiceLocator.getVentaService().buscarCobro(codigoBuscar, estadoBuscar, fechaDesdeBuscar, fechaHastaBuscar);
			
			FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Advertencia", Mensajes.OPERACION_EXITOSA);  
			RequestContext.getCurrentInstance().showMessageInDialog(message);
			
			return null;

		} else {
			
			FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Advertencia", Mensajes.ELEMENTO_NO_SELECCIONADO);  
	        RequestContext.getCurrentInstance().showMessageInDialog(message);
			return null;
		}	

	}

	public String buscarCobro() {
		
			
		this.cobros = ServiceLocator.getVentaService().buscarCobro(codigoBuscar, estadoBuscar, fechaDesdeBuscar, fechaHastaBuscar);

		if (this.cobros != null && !this.cobros.isEmpty()) {

			return null;

		} else {

			FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Advertencia", "No se encotraron resultados para la busqueda.");  
			RequestContext.getCurrentInstance().showMessageInDialog(message);
			return null;		
		}
	}
	
	public void visibilizarBuscar() {
		
		panelBuscarVisibilidad = true;
		panelEditarVisibilidad = false;
		panelRegistrarVisibilidad = false;
	}
	
	public void visibilizarRegistrar() {
		
		panelBuscarVisibilidad = false;
		panelEditarVisibilidad = false;
		panelRegistrarVisibilidad = true;
	}
	
	public void volverBusqueda() {
		
		panelBuscarVisibilidad = true;
		panelEditarVisibilidad = false;
		this.cobros = ServiceLocator.getVentaService().buscarCobro(codigoBuscar, estadoBuscar, fechaDesdeBuscar, fechaHastaBuscar);
	}
	
}
